1
2
3
4
5
6
7 package io.vavr.collection;
8
9 import io.vavr.Function2;
10 import io.vavr.Tuple2;
11 import org.assertj.core.api.Assertions;
12 import org.junit.Test;
13
14 import java.util.List;
15 import java.util.Random;
16 import java.util.concurrent.ThreadLocalRandom;
17 import java.util.function.Function;
18 import java.util.function.Predicate;
19
20 import static io.vavr.API.Tuple;
21 import static org.assertj.core.api.Assertions.assertThat;
22
23 public class VectorPropertyTest {
24
25 @Test
26 public void shouldCreateAndGet() {
27 for (int i = 0; i < 500; i++) {
28 final Seq<Integer> expected = Array.range(0, i);
29 final Vector<Integer> actual = Vector.ofAll(expected);
30 for (int j = 0; j < actual.size(); j++) {
31 assertThat(expected.get(j)).isEqualTo(actual.get(j));
32 }
33
34 assert (i == 0) || !actual.trie.type.type().isPrimitive();
35
36
37 final Seq<Boolean> expectedBoolean = expected.map(v -> v > 0);
38 final Vector<Boolean> actualBoolean = Vector.ofAll(ArrayType.<boolean[]> asPrimitives(boolean.class, expectedBoolean));
39 assert (i == 0) || (actualBoolean.trie.type.type() == boolean.class);
40 assertAreEqual(expectedBoolean, actualBoolean);
41 assertAreEqual(expectedBoolean.append(null), actualBoolean.append(null));
42
43
44 final Seq<Byte> expectedByte = expected.map(Integer::byteValue);
45 final Vector<Byte> actualByte = Vector.ofAll(ArrayType.<byte[]> asPrimitives(byte.class, expectedByte));
46 assert (i == 0) || (actualByte.trie.type.type() == byte.class);
47 assertAreEqual(expectedByte, actualByte);
48 assertAreEqual(expectedByte.append(null), actualByte.append(null));
49
50
51 final Seq<Character> expectedChar = expected.map(v -> (char) v.intValue());
52 final Vector<Character> actualChar = Vector.ofAll(ArrayType.<char[]> asPrimitives(char.class, expectedChar));
53 assert (i == 0) || (actualChar.trie.type.type() == char.class);
54 assertAreEqual(expectedChar, actualChar);
55 assertAreEqual(expectedChar.append(null), actualChar.append(null));
56
57
58 final Seq<Double> expectedDouble = expected.map(Integer::doubleValue);
59 final Vector<Double> actualDouble = Vector.ofAll(ArrayType.<double[]> asPrimitives(double.class, expectedDouble));
60 assert (i == 0) || (actualDouble.trie.type.type() == double.class);
61 assertAreEqual(expectedDouble, actualDouble);
62 assertAreEqual(expectedDouble.append(null), actualDouble.append(null));
63
64
65 final Seq<Float> expectedFloat = expected.map(Integer::floatValue);
66 final Vector<Float> actualFloat = Vector.ofAll(ArrayType.<float[]> asPrimitives(float.class, expectedFloat));
67 assert (i == 0) || (actualFloat.trie.type.type() == float.class);
68 assertAreEqual(expectedFloat, actualFloat);
69 assertAreEqual(expectedFloat.append(null), actualFloat.append(null));
70
71
72 final Vector<Integer> actualInt = Vector.ofAll(ArrayType.<int[]> asPrimitives(int.class, expected));
73 assert (i == 0) || (actualInt.trie.type.type() == int.class);
74 assertAreEqual(expected, actualInt);
75 assertAreEqual(expected.append(null), actual.append(null));
76
77
78 final Seq<Long> expectedLong = expected.map(Integer::longValue);
79 final Vector<Long> actualLong = Vector.ofAll(ArrayType.<long[]> asPrimitives(long.class, expectedLong));
80 assert (i == 0) || (actualLong.trie.type.type() == long.class);
81 assertAreEqual(expectedLong, actualLong);
82 assertAreEqual(expectedLong.append(null), actualLong.append(null));
83
84
85 final Seq<Short> expectedShort = expected.map(Integer::shortValue);
86 final Vector<Short> actualShort = Vector.ofAll(ArrayType.<short[]> asPrimitives(short.class, expectedShort));
87 assert (i == 0) || (actualShort.trie.type.type() == short.class);
88 assertAreEqual(expectedShort, actualShort);
89 assertAreEqual(expectedShort.append(null), actualShort.append(null));
90 }
91 }
92
93 @Test
94 public void shouldIterate() {
95 for (byte depth = 0; depth <= 2; depth++) {
96 for (int i = 0; i < 5000; i++) {
97 final Seq<Integer> expected = Array.range(0, i);
98 final Vector<Integer> actual = Vector.ofAll(expected);
99 assertAreEqual(actual, expected);
100 }
101 }
102
103 Seq<Integer> expected = Array.range(0, 1000);
104 Vector<Integer> actual = Vector.ofAll(ArrayType.<int[]> asPrimitives(int.class, expected));
105 for (int drop = 0; drop <= (BitMappedTrie.BRANCHING_FACTOR + 1); drop++) {
106 final Iterator<Integer> expectedIterator = expected.iterator();
107 actual.trie.<int[]> visit((index, leaf, start, end) -> {
108 for (int i = start; i < end; i++) {
109 assertThat(leaf[i]).isEqualTo(expectedIterator.next());
110 }
111 return -1;
112 });
113
114 expected = expected.tail().init();
115 actual = actual.tail().init();
116 }
117 }
118
119 @Test
120 public void shouldPrepend() {
121 Seq<Integer> expected = Array.empty();
122 Vector<Integer> actual = Vector.empty();
123
124 for (int drop = 0; drop <= (BitMappedTrie.BRANCHING_FACTOR + 1); drop++) {
125 for (Integer value : Iterator.range(0, 1000)) {
126 expected = expected.drop(drop);
127 actual = assertAreEqual(actual, drop, Vector::drop, expected);
128
129 expected = expected.prepend(value);
130 actual = assertAreEqual(actual, value, Vector::prepend, expected);
131 }
132 }
133 }
134
135 @Test
136 public void shouldAppend() {
137 Seq<Integer> expected = Array.empty();
138 Vector<Integer> actual = Vector.empty();
139
140 for (int drop = 0; drop <= (BitMappedTrie.BRANCHING_FACTOR + 1); drop++) {
141 for (Integer value : Iterator.range(0, 500)) {
142 expected = expected.drop(drop);
143 actual = assertAreEqual(actual, drop, Vector::drop, expected);
144
145 expected = expected.append(value);
146 actual = assertAreEqual(actual, value, Vector::append, expected);
147 }
148 }
149 }
150
151 @Test
152 public void shouldUpdate() {
153 final Function<Integer, Integer> mapper = i -> i + 1;
154
155 for (byte depth = 0; depth <= 2; depth++) {
156 final int length = 10_000;
157
158 for (int drop = 0; drop <= (BitMappedTrie.BRANCHING_FACTOR + 1); drop++) {
159 Seq<Integer> expected = Array.range(0, length);
160 Vector<Integer> actual = Vector.ofAll(expected);
161
162 expected = expected.drop(drop);
163 actual = assertAreEqual(actual, drop, Vector::drop, expected);
164
165 for (int i = 0; i < actual.length(); i++) {
166 final Integer newValue = mapper.apply(actual.get(i));
167 actual = actual.update(i, newValue);
168 }
169
170 assertAreEqual(actual, 0, (a, p) -> a, expected.map(mapper));
171 }
172 }
173 }
174
175 @Test
176 public void shouldDrop() {
177 final Seq<Integer> expected = Array.range(0, 2_000);
178 final Vector<Integer> actual = Vector.ofAll(expected);
179
180 Vector<Integer> actualSingleDrop = actual;
181 for (int i = 0; i <= expected.length(); i++) {
182 final Seq<Integer> expectedDrop = expected.drop(i);
183
184 assertAreEqual(actual, i, Vector::drop, expectedDrop);
185 assertAreEqual(actualSingleDrop, null, (a, p) -> a, expectedDrop);
186
187 actualSingleDrop = actualSingleDrop.drop(1);
188 }
189 }
190
191 @Test
192 public void shouldDropRight() {
193 final Seq<Integer> expected = Array.range(0, 2_000);
194 final Vector<Integer> actual = Vector.ofAll(expected);
195
196 Vector<Integer> actualSingleDrop = actual;
197 for (int i = 0; i <= expected.length(); i++) {
198 final Seq<Integer> expectedDrop = expected.dropRight(i);
199
200 assertAreEqual(actual, i, Vector::dropRight, expectedDrop);
201 assertAreEqual(actualSingleDrop, null, (a, p) -> a, expectedDrop);
202
203 actualSingleDrop = actualSingleDrop.dropRight(1);
204 }
205 }
206
207 @Test
208 public void shouldSlice() {
209 for (int length = 1, end = 500; length <= end; length++) {
210 Seq<Integer> expected = Array.range(0, length);
211 Vector<Integer> actual = Vector.ofAll(expected);
212
213 for (int i = 0; i <= expected.length(); i++) {
214 expected = expected.slice(1, expected.size() - 1);
215 actual = assertAreEqual(actual, i, (a, p) -> a.slice(1, a.size() - 1), expected);
216 }
217 }
218 }
219
220 @Test
221 public void shouldBehaveLikeArray() {
222 final int seed = ThreadLocalRandom.current().nextInt();
223 System.out.println("using seed " + seed);
224 final Random random = new Random(seed);
225
226 for (int i = 1; i < 10; i++) {
227 Seq<Object> expected = Array.empty();
228 Vector<Object> actual = Vector.empty();
229 for (int j = 0; j < 20_000; j++) {
230 Seq<Tuple2<Seq<Object>, Vector<Object>>> history = Array.empty();
231
232 if (percent(random) < 20) {
233 expected = Array.ofAll(Vector.ofAll(randomValues(random, 100)).filter(v -> v instanceof Integer));
234 actual = (percent(random) < 30) ? Vector.narrow(Vector.ofAll(ArrayType.<int[]> asPrimitives(int.class, expected))) : Vector.ofAll(expected);
235 assertAreEqual(expected, actual);
236 history = history.append(Tuple(expected, actual));
237 }
238
239 if (percent(random) < 50) {
240 final Object value = randomValue(random);
241 expected = expected.append(value);
242 actual = assertAreEqual(actual, value, Vector::append, expected);
243 history = history.append(Tuple(expected, actual));
244 }
245 if (percent(random) < 10) {
246 Iterable<Object> values = randomValues(random, random.nextInt(2 * BitMappedTrie.BRANCHING_FACTOR));
247 expected = expected.appendAll(values);
248
249 values = (percent(random) < 50) ? Iterator.ofAll(values.iterator()) : values;
250 actual = assertAreEqual(actual, values, Vector::appendAll, expected);
251 history = history.append(Tuple(expected, actual));
252 }
253
254 if (percent(random) < 50) {
255 final Object value = randomValue(random);
256 expected = expected.prepend(value);
257 actual = assertAreEqual(actual, value, Vector::prepend, expected);
258 history = history.append(Tuple(expected, actual));
259 }
260 if (percent(random) < 10) {
261 Iterable<Object> values = randomValues(random, random.nextInt(2 * BitMappedTrie.BRANCHING_FACTOR));
262 expected = expected.prependAll(values);
263
264 values = (percent(random) < 50) ? Iterator.ofAll(values) : values;
265 actual = assertAreEqual(actual, values, Vector::prependAll, expected);
266 history = history.append(Tuple(expected, actual));
267 }
268
269 if (percent(random) < 30) {
270 final int n = random.nextInt(expected.size() + 1);
271 expected = expected.drop(n);
272 actual = assertAreEqual(actual, n, Vector::drop, expected);
273 history = history.append(Tuple(expected, actual));
274 }
275
276 if (percent(random) < 10) {
277 final int index = random.nextInt(expected.size() + 1);
278 Iterable<Object> values = randomValues(random, random.nextInt(2 * BitMappedTrie.BRANCHING_FACTOR));
279 expected = expected.insertAll(index, values);
280
281 values = (percent(random) < 50) ? Iterator.ofAll(values) : values;
282 actual = assertAreEqual(actual, values, (a, p) -> a.insertAll(index, p), expected);
283 history = history.append(Tuple(expected, actual));
284 }
285
286 if (percent(random) < 30) {
287 final int n = random.nextInt(expected.size() + 1);
288 expected = expected.take(n);
289 actual = assertAreEqual(actual, n, Vector::take, expected);
290 history = history.append(Tuple(expected, actual));
291 }
292
293 if (!expected.isEmpty()) {
294 assertThat(actual.head()).isEqualTo(expected.head());
295 Assertions.assertThat(actual.tail().toJavaList()).isEqualTo(expected.tail().toJavaList());
296 history = history.append(Tuple(expected, actual));
297 }
298
299 if (!expected.isEmpty()) {
300 final int index = random.nextInt(expected.size());
301 assertThat(actual.get(index)).isEqualTo(expected.get(index));
302 history = history.append(Tuple(expected, actual));
303 }
304
305 if (percent(random) < 50) {
306 if (!expected.isEmpty()) {
307 final int index = random.nextInt(expected.size());
308 final Object value = randomValue(random);
309 expected = expected.update(index, value);
310 actual = assertAreEqual(actual, null, (a, p) -> a.update(index, value), expected);
311 history = history.append(Tuple(expected, actual));
312 }
313 }
314
315 if (percent(random) < 20) {
316 final Function<Object, Object> mapper = val -> (val instanceof Integer) ? ((Integer) val + 1) : val;
317 expected = expected.map(mapper);
318 actual = assertAreEqual(actual, null, (a, p) -> a.map(mapper), expected);
319 history = history.append(Tuple(expected, actual));
320 }
321
322 if (percent(random) < 30) {
323 final Predicate<Object> filter = val -> (String.valueOf(val).length() % 10) == 0;
324 expected = expected.filter(filter);
325 actual = assertAreEqual(actual, null, (a, p) -> a.filter(filter), expected);
326 history = history.append(Tuple(expected, actual));
327 }
328
329 if (percent(random) < 30) {
330 for (int k = 0; k < 2; k++) {
331 if (!expected.isEmpty()) {
332 final int to = random.nextInt(expected.size());
333 final int from = random.nextInt(to + 1);
334 expected = expected.slice(from, to);
335 actual = assertAreEqual(actual, null, (a, p) -> a.slice(from, to), expected);
336 history = history.append(Tuple(expected, actual));
337 }
338 }
339 }
340
341 history.forEach(t -> assertAreEqual(t._1, t._2));
342 }
343 }
344 }
345
346 private int percent(Random random) { return random.nextInt(101); }
347 private Iterable<Object> randomValues(Random random, int count) {
348 final Vector<Object> values = Vector.range(0, count).map(v -> randomValue(random));
349 final int percent = percent(random);
350 if (percent < 30) {
351 return values.toJavaList();
352 } else {
353 return values;
354 }
355 }
356 private Object randomValue(Random random) {
357 final int percent = percent(random);
358 if (percent < 5) {
359 return null;
360 } else if (percent < 10) {
361 return "String";
362 } else {
363 return random.nextInt();
364 }
365 }
366
367 private static <T extends Seq<?>, P> T assertAreEqual(T previousActual, P param, Function2<T, P, T> actualProvider, Seq<?> expected) {
368 final T actual = actualProvider.apply(previousActual, param);
369 assertAreEqual(expected, actual);
370 return actual;
371 }
372
373 private static void assertAreEqual(Seq<?> expected, Seq<?> actual) {
374 final List<?> actualList = actual.toJavaList();
375 final List<?> expectedList = expected.toJavaList();
376 assertThat(actualList).isEqualTo(expectedList);
377 }
378 }